package com.gitee.wsl.compose.ui.calendar.view

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.onClick
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.gitee.wsl.compose.ui.calendar.CalendarAdapter
import com.gitee.wsl.compose.ui.calendar.utils.Pallete
import com.gitee.wsl.time.calendar.bean.CalendarDay
import com.gitee.wsl.time.calendar.style.DayPosition
import com.gitee.wsl.time.calendar.style.DayState


object Day

typealias DaySlate =  @Composable BoxScope.(CalendarDay) -> Unit

val Day.default: DaySlate
    get() = { day ->
		Text(
		"${day.date.dayOfMonth}",
		fontSize = 20.sp,
		textAlign = TextAlign.Center,
	    )
	}

typealias DayAdapterSlate =  @Composable BoxScope.(CalendarDay, adapter: CalendarAdapter) -> Unit


fun Day.useAdapter(adapter: CalendarAdapter,daySlate: DayAdapterSlate = defaultDayAdapter):DaySlate =  { a ->  daySlate(a,adapter)}

internal val Day.defaultDayAdapter:DayAdapterSlate get() = { day,adapter ->
	val state = DayState(
		date = day.date,
		isActiveDay = adapter.isActiveDay(day.date),
		enabled = adapter.isEnabled(day.date),
		isForPreviousMonth = day.position == DayPosition.InDate,
		isForNextMonth = day.position == DayPosition.OutDate,
	)
	CalendarDay(state = state, selected = adapter.isSelected(day.date), onClick = { adapter.changeSelected(day.date) })
}


/**
 * Composable function to display a calendar day.
 *
 * @param state The state of the day.
 * @param interactionSource The interaction source for the view.
 * @param onClick The callback to be invoked when the view is clicked.
 * @param modifier The modifier for the view.
 */
@Composable
fun CalendarDay(
	state: DayState,
	interactionSource: MutableInteractionSource = MutableInteractionSource(),
	selected: Boolean = false,
	onClick: () -> Unit = {},
	modifier: Modifier = Modifier,
) = with(state) {
	Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth()) {
		OutlinedButton(
			onClick = onClick,
			modifier = modifier,
			shape = RoundedCornerShape(50.dp),
			border = BorderStroke(1.dp, Color.Transparent),
			contentPadding = PaddingValues(0.dp),
			interactionSource = remember { interactionSource },
			enabled = enabled,
			colors =
			ButtonDefaults.outlinedButtonColors(
				contentColor =
				if (isForPreviousMonth || isForNextMonth) {
					Color.LightGray
				} else {
					if (isActiveDay)
						Pallete.LightRed
					else if(selected)
						Pallete.LightBlue
					else
						Pallete.LightGreen
				},
			),
		) {
			Text(
				"${date.dayOfMonth}",
				fontSize = 20.sp,
				textAlign = TextAlign.Center,
			)
		}
	}
}

val Day.defaultDayAdapterUseCircle:DayAdapterSlate get() = { day,adapter ->
//	val state = DayState(
//		date = day.date,
//		isActiveDay = adapter.isActiveDay(day.date),
//		enabled = adapter.isEnabled(day.date),
//		isForPreviousMonth = day.position == DayPosition.InDate,
//		isForNextMonth = day.position == DayPosition.OutDate,
//	)
	DayUseCircle(day = day, isSelected  = adapter.isSelected(day.date), onClick = { adapter.changeSelected(day.date) })
}

@Composable
private fun DayUseCircle(day: CalendarDay, isSelected: Boolean, onClick: (CalendarDay) -> Unit) {
	Box(
        modifier = Modifier
			.aspectRatio(1f) // This is important for square-sizing!
			.testTag("MonthDay")
			.padding(6.dp)
			.clip(CircleShape)
			.background(color = if (isSelected) Color.Blue else Color.Transparent)
			// Disable clicks on inDates/outDates
			.clickable(
				enabled = day.position == DayPosition.RangeDate,
				showRipple = !isSelected,
				onClick = { onClick(day) },
			),
        contentAlignment = Alignment.Center,
    ) {
        val textColor = when (day.position) {
            // Color.Unspecified will use the default text color from the current theme
            DayPosition.RangeDate -> if (isSelected) Color.White else Color.Unspecified
            DayPosition.InDate, DayPosition.OutDate -> Color.Gray
        }
        Text(
            text = day.date.dayOfMonth.toString(),
            color = textColor,
            fontSize = 14.sp,
        )
    }
}

internal fun Modifier.clickable(
	enabled: Boolean = true,
	showRipple: Boolean = true,
	onClickLabel: String? = null,
	role: Role? = null,
	onClick: () -> Unit,
): Modifier = composed {
	clickable(
		interactionSource = remember { MutableInteractionSource() },
		indication = if (showRipple) LocalIndication.current else null,
		enabled = enabled,
		onClickLabel = onClickLabel,
		role = role,
		onClick = onClick,
	)
}